import os
import hashlib
import json
from datetime import datetime
import re
import uuid
from typing import Any, Dict, List, Optional, Union

# 文件处理工具类
class FileUtils:
    @staticmethod
    def ensure_dir_exists(directory: str) -> None:
        """确保目录存在，如果不存在则创建"""
        if not os.path.exists(directory):
            os.makedirs(directory)
    
    @staticmethod
    def get_file_extension(filename: str) -> str:
        """获取文件扩展名"""
        return os.path.splitext(filename)[1].lower()
    
    @staticmethod
    def generate_unique_filename(original_filename: str) -> str:
        """生成唯一的文件名"""
        timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
        random_str = uuid.uuid4().hex[:8]
        ext = FileUtils.get_file_extension(original_filename)
        base_name = os.path.splitext(os.path.basename(original_filename))[0]
        # 清理基础名称，移除特殊字符
        base_name = re.sub(r'[^a-zA-Z0-9]', '_', base_name)
        return f"{base_name}_{timestamp}_{random_str}{ext}"
    
    @staticmethod
    def read_file_content(file_path: str) -> Optional[str]:
        """读取文件内容"""
        try:
            with open(file_path, 'r', encoding='utf-8') as file:
                return file.read()
        except Exception as e:
            print(f"读取文件失败 {file_path}: {str(e)}")
            return None
    
    @staticmethod
    def write_file_content(file_path: str, content: str) -> bool:
        """写入文件内容"""
        try:
            # 确保目录存在
            FileUtils.ensure_dir_exists(os.path.dirname(file_path))
            with open(file_path, 'w', encoding='utf-8') as file:
                file.write(content)
            return True
        except Exception as e:
            print(f"写入文件失败 {file_path}: {str(e)}")
            return False
    
    @staticmethod
    def delete_file(file_path: str) -> bool:
        """删除文件"""
        try:
            if os.path.exists(file_path):
                os.remove(file_path)
                return True
            return False
        except Exception as e:
            print(f"删除文件失败 {file_path}: {str(e)}")
            return False

# 日期时间工具类
class DateUtils:
    @staticmethod
    def now() -> datetime:
        """获取当前时间"""
        return datetime.now()
    
    @staticmethod
    def format_datetime(dt: datetime, format_str: str = '%Y-%m-%d %H:%M:%S') -> str:
        """格式化日期时间"""
        return dt.strftime(format_str)
    
    @staticmethod
    def format_date(dt: datetime, format_str: str = '%Y-%m-%d') -> str:
        """格式化日期"""
        return dt.strftime(format_str)
    
    @staticmethod
    def parse_datetime(date_str: str, format_str: str = '%Y-%m-%d %H:%M:%S') -> Optional[datetime]:
        """解析日期时间字符串"""
        try:
            return datetime.strptime(date_str, format_str)
        except ValueError:
            return None
    
    @staticmethod
    def parse_date(date_str: str, format_str: str = '%Y-%m-%d') -> Optional[datetime]:
        """解析日期字符串"""
        try:
            return datetime.strptime(date_str, format_str)
        except ValueError:
            return None
    
    @staticmethod
    def is_valid_date(date_str: str, format_str: str = '%Y-%m-%d') -> bool:
        """检查日期字符串是否有效"""
        return DateUtils.parse_date(date_str, format_str) is not None

# 数据验证工具类
class ValidationUtils:
    @staticmethod
    def is_valid_email(email: str) -> bool:
        """验证邮箱格式是否正确"""
        pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
        return re.match(pattern, email) is not None
    
    @staticmethod
    def is_valid_phone(phone: str) -> bool:
        """验证手机号格式是否正确（中国手机号）"""
        pattern = r"^1[3-9]\d{9}$"
        return re.match(pattern, phone) is not None
    
    @staticmethod
    def is_valid_url(url: str) -> bool:
        """验证URL格式是否正确"""
        pattern = r"^https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+"
        return re.match(pattern, url) is not None
    
    @staticmethod
    def is_valid_id_card(id_card: str) -> bool:
        """验证身份证号格式是否正确（中国身份证）"""
        # 简单验证，实际应用中可能需要更复杂的验证
        pattern = r"^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$")
        return re.match(pattern, id_card) is not None

# 字符串处理工具类
class StringUtils:
    @staticmethod
    def truncate(text: str, max_length: int, suffix: str = '...') -> str:
        """截断字符串"""
        if len(text) <= max_length:
            return text
        return text[:max_length] + suffix
    
    @staticmethod
    def remove_html_tags(text: str) -> str:
        """移除HTML标签"""
        pattern = r'<[^>]+>'
        return re.sub(pattern, '', text)
    
    @staticmethod
    def sanitize_text(text: str) -> str:
        """清理文本，移除特殊字符"""
        # 只保留常见字符和中文
        pattern = r'[^a-zA-Z0-9\u4e00-\u9fa5,.?!，。？！:：;；\-\s]'
        return re.sub(pattern, '', text)
    
    @staticmethod
    def to_snake_case(text: str) -> str:
        """转换为蛇形命名法"""
        # 处理驼峰命名
        text = re.sub(r'(?<!^)(?=[A-Z])', '_', text)
        # 处理空格和其他分隔符
        text = re.sub(r'[\s\-]+', '_', text)
        return text.lower()
    
    @staticmethod
    def to_camel_case(text: str) -> str:
        """转换为驼峰命名法"""
        # 分割文本
        parts = re.split(r'[\s\-_]+', text)
        # 首字母大写其余部分
        return parts[0].lower() + ''.join(word.capitalize() for word in parts[1:])

# 数据转换工具类
class ConversionUtils:
    @staticmethod
    def to_json(data: Any) -> Optional[str]:
        """转换为JSON字符串"""
        try:
            return json.dumps(data, ensure_ascii=False)
        except (TypeError, ValueError):
            return None
    
    @staticmethod
    def from_json(json_str: str) -> Optional[Any]:
        """从JSON字符串解析数据"""
        try:
            return json.loads(json_str)
        except (TypeError, ValueError):
            return None
    
    @staticmethod
    def convert_to_int(value: Any, default: int = 0) -> int:
        """转换为整数"""
        try:
            return int(value)
        except (TypeError, ValueError):
            return default
    
    @staticmethod
    def convert_to_float(value: Any, default: float = 0.0) -> float:
        """转换为浮点数"""
        try:
            return float(value)
        except (TypeError, ValueError):
            return default
    
    @staticmethod
    def convert_to_bool(value: Any, default: bool = False) -> bool:
        """转换为布尔值"""
        if isinstance(value, bool):
            return value
        if isinstance(value, str):
            return value.lower() in ('true', 'yes', '1', 'y', 't')
        if isinstance(value, (int, float)):
            return value != 0
        return default

# 加密工具类
class EncryptionUtils:
    @staticmethod
    def md5_hash(text: str) -> str:
        """计算MD5哈希值"""
        return hashlib.md5(text.encode('utf-8')).hexdigest()
    
    @staticmethod
    def sha256_hash(text: str) -> str:
        """计算SHA-256哈希值"""
        return hashlib.sha256(text.encode('utf-8')).hexdigest()
    
    @staticmethod
    def generate_token(length: int = 32) -> str:
        """生成随机令牌"""
        return uuid.uuid4().hex[:length]

# 列表和字典处理工具类
class CollectionUtils:
    @staticmethod
    def chunk_list(lst: List[Any], chunk_size: int) -> List[List[Any]]:
        """将列表分割成指定大小的块"""
        return [lst[i:i+chunk_size] for i in range(0, len(lst), chunk_size)]
    
    @staticmethod
    def flatten_list(nested_list: List[Any]) -> List[Any]:
        """展平嵌套列表"""
        result = []
        for item in nested_list:
            if isinstance(item, list):
                result.extend(CollectionUtils.flatten_list(item))
            else:
                result.append(item)
        return result
    
    @staticmethod
    def merge_dicts(*dicts: Dict[Any, Any]) -> Dict[Any, Any]:
        """合并多个字典"""
        result = {}
        for d in dicts:
            result.update(d)
        return result
    
    @staticmethod
    def filter_dict(d: Dict[Any, Any], keys: List[Any]) -> Dict[Any, Any]:
        """根据键列表过滤字典"""
        return {k: d[k] for k in keys if k in d}
    
    @staticmethod
    def remove_none_values(d: Dict[Any, Any]) -> Dict[Any, Any]:
        """移除字典中的None值"""
        return {k: v for k, v in d.items() if v is not None}

# 错误处理工具类
class ErrorUtils:
    @staticmethod
    def format_error_message(error: Exception) -> str:
        """格式化错误信息"""
        return f"{type(error).__name__}: {str(error)}"
    
    @staticmethod
    def get_error_traceback(error: Exception) -> str:
        """获取错误堆栈信息"""
        import traceback
        return traceback.format_exc()
    
    @staticmethod
    def is_network_error(error: Exception) -> bool:
        """检查是否为网络错误"""
        import requests.exceptions
        network_exceptions = (
            requests.exceptions.RequestException,
            ConnectionError,
            TimeoutError
        )
        return isinstance(error, network_exceptions)

# 分页工具类
class PaginationUtils:
    @staticmethod
    def paginate(data: List[Any], page: int, page_size: int) -> Dict[str, Any]:
        """分页处理数据"""
        # 确保页码和页大小有效
        page = max(1, page)
        page_size = max(1, page_size)
        
        # 计算总页数
        total_items = len(data)
        total_pages = (total_items + page_size - 1) // page_size
        
        # 确保页码不超过总页数
        page = min(page, max(1, total_pages))
        
        # 计算起始和结束索引
        start_index = (page - 1) * page_size
        end_index = start_index + page_size
        
        # 获取当前页数据
        items = data[start_index:end_index]
        
        return {
            'items': items,
            'page': page,
            'page_size': page_size,
            'total_items': total_items,
            'total_pages': total_pages,
            'has_next': page < total_pages,
            'has_prev': page > 1
        }

# 缓存工具类（简单内存缓存）
class CacheUtils:
    _cache = {}
    
    @staticmethod
    def set(key: str, value: Any, expire_seconds: int = 3600) -> None:
        """设置缓存"""
        CacheUtils._cache[key] = {
            'value': value,
            'expire_at': datetime.now().timestamp() + expire_seconds
        }
    
    @staticmethod
    def get(key: str) -> Optional[Any]:
        """获取缓存"""
        if key not in CacheUtils._cache:
            return None
        
        cache_item = CacheUtils._cache[key]
        # 检查是否过期
        if datetime.now().timestamp() > cache_item['expire_at']:
            del CacheUtils._cache[key]
            return None
        
        return cache_item['value']
    
    @staticmethod
    def delete(key: str) -> None:
        """删除缓存"""
        if key in CacheUtils._cache:
            del CacheUtils._cache[key]
    
    @staticmethod
    def clear() -> None:
        """清空缓存"""
        CacheUtils._cache.clear()